/**
 * 版权所有（c）2021. 上海海鼎信息工程股份有限公司，保留所有权利
 */
package com.lovely602.thread;

import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

import lombok.extern.slf4j.Slf4j;

/**
 * @author lizhixing
 */
@Slf4j
public class ExecutorServiceDemo {

  /** 任务数量 */
  private static final AtomicInteger taskNum = new AtomicInteger(0);
  /** 可重入锁：公平锁 */
  private static final Lock lock = new ReentrantLock();

  public static void main(String[] args) throws InterruptedException, ExecutionException {

    ExecutorService executorService = new ThreadPoolExecutor(7, 10, 1L, TimeUnit.SECONDS,
        new LinkedBlockingQueue<>(1000), Executors.defaultThreadFactory(),
        new ThreadPoolExecutor.DiscardPolicy());
    System.out.println("程序开始运行");
    long begin = System.currentTimeMillis();
    int sum = 1000;
    for (int i = 0; i < sum; i++) {
      executorService.submit(() -> addBySecond());
    }
    boolean result = true;
    // executorService.shutdown();
    do {
      long beginMin = System.currentTimeMillis();
      result = !executorService.awaitTermination(3, TimeUnit.SECONDS);
      System.out.println("过程中执行结果是：" + taskNum);
      System.out.println("awaitTermination返回的值是：" + !result);
      if (taskNum.get() == sum) {
        result = false;
      }
      long beginMax = System.currentTimeMillis();
      System.out.println("一次doWhile循环耗时是：" + (beginMax - beginMin));
    } while (result);
    System.out.println("程序结束运行");
    System.out.println("程序运行结果是：" + taskNum);
    long end = System.currentTimeMillis();
    System.out.println("线程执行耗时是：" + (end - begin));
  }

  private static void addBySecond() {
    try {
      Thread.sleep(1000);
      System.out.println("任务：" + taskNum + "  " + Thread.currentThread().getName() + " 正在执行");
    } catch (Exception e) {
      log.error("叠加失败", e);
    } finally {
      lock.lock();
      taskNum.addAndGet(1);
      lock.unlock();
    }
  }

}
